package com.app.service.impl.article;

import com.app.domain.bo.article.TagBo;
import com.app.domain.page.Page;
import com.app.domain.po.article.ArticleTagPo;
import com.app.domain.po.article.TagPo;
import com.app.domain.vo.article.TagVo;
import com.app.framework.utils.CoBeanUtils;
import com.app.framework.utils.CollectionUtils;
import com.app.mapper.article.TagMapper;
import com.app.service.article.ArticleTagService;
import com.app.service.article.TagService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import jakarta.annotation.Resource;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.*;

/**
 * 标签方法实现
 */
@Service
public class TagServiceImpl extends ServiceImpl<TagMapper, TagPo> implements TagService {

    @Resource
    private ArticleTagService articleTagService;

    /**
     * 标签列表
     *
     * @param bo 入参
     */
    @Override
    @Cacheable(cacheNames = "tags", key = "#bo.getPageNum")
    public Page<TagVo> lists(TagBo bo) {
        PageHelper.startPage(bo.getPageNum(), bo.getPageSize());
        List<TagVo> tagVos = baseMapper.lists();
        return Page.restPage(tagVos);
    }

    /**
     * 添加标签 - 单个
     *
     * @param bo 入参
     */
    @Override
    @CacheEvict(cacheNames = "tags", allEntries = true)
    public void saveOne(TagBo bo) {
        Boolean determine = baseMapper.selectTagByName(bo.getName());
        Assert.state(!determine, "标签已存在");
        TagPo tagPo = CoBeanUtils.copy(bo, TagPo.class);
        tagPo.setCreateTime(new Date());
        tagPo.setUpdateTime(new Date());
        baseMapper.insert(tagPo);
    }

    /**
     * 批量添加标签
     *
     * @param names 标签名称
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = "tags", allEntries = true)
    public void batchSave(List<String> names) {
        Assert.state(CollectionUtils.isNoNull(names), "标签不能为空");
        List<TagVo> tagVos = baseMapper.selectTagByNames(names);
        Assert.state(CollectionUtils.isEmpty(tagVos), "标签有重复");
        List<TagPo> tagPos = new ArrayList<>();
        Set<String> distinctNames = new HashSet<>(names);
        for (String name : distinctNames) {
            TagPo tagPo = new TagPo();
            tagPo.setName(name);
            tagPo.setCreateTime(new Date());
            tagPo.setUpdateTime(new Date());
            tagPos.add(tagPo);
        }
        saveBatch(tagPos);
    }

    /**
     * 标签详情
     *
     * @param tagId 标签ID
     */
    @Override
    @Cacheable(cacheNames = "tags_details", key = "#tagId")
    public TagPo details(Long tagId) {
        TagPo tagPo = baseMapper.selectById(tagId);
        Assert.notNull(tagPo, "标签不存在");
        return baseMapper.selectById(tagId);
    }

    /**
     * 修改标签
     *
     * @param bo 入参
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = {"tags", "tags_details"}, allEntries = true)
    public void updateOne(TagBo bo) {
        Boolean determine = baseMapper.selectTagByName(bo.getName());
        Assert.state(!determine, "标签有重复");
        TagPo tagPo = CoBeanUtils.copy(bo, TagPo.class);
        tagPo.setUpdateTime(new Date());
        baseMapper.updateById(tagPo);
    }

    /**
     * 删除标签
     *
     * @param tagId 标签ID
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = {"tags", "tags_details"}, allEntries = true)
    public void deleteOne(Long tagId) {
        TagPo tagPo = baseMapper.selectById(tagId);
        Assert.notNull(tagPo, "标签不存在");
        baseMapper.deleteById(tagId);
        //删除文章关联标签
        articleTagService.lambdaUpdate().eq(ArticleTagPo::getTagId, tagId).remove();
    }

}